﻿#include "DSP281x_Device.h"  // 引入官方设备头文件

// 系统初始化函数
void InitPll(void)
{
    int i;
    EALLOW;
    SysCtrlRegs.PLLCR.bit.DIV = 10;  // 系统时钟 = 外部时钟 * PLLCR / 2
    EDIS;
    for(i = 0; i < 100; i++) {;}  // 等待PLL稳定
}

void InitPeripheralClocks(void)
{
    EALLOW;
    SysCtrlRegs.HISPCP.all = 1;  // HISPCLK = SYSCLK * HISPCP / 2
    SysCtrlRegs.LOSPCP.all = 2;  // LOSPCLK = SYSCLK * LOSPCP / 2
    SysCtrlRegs.PCLKCR.all = 0xffff;  // 使能所有外设时钟
    EDIS;
}

void DisableDog(void)
{
    EALLOW;
    SysCtrlRegs.WDCR = 0x0068;  // 关闭看门狗
    EDIS;
}

void InitSysCtrl(void)
{
    DisableDog();
    InitPll();
    InitPeripheralClocks();
}

// SCI初始化函数
void InitSci(void)
{
    // 配置GPIO引脚为SCI功能
    EALLOW;
    GpioMuxRegs.GPFMUX.all = 0x0030;  // 设置GPIO F4和F5为SCI功能 (F4=SCITXD, F5=SCIRXD)
    GpioMuxRegs.GPFDIR.all |= 0x0010;  // 设置F4为输出（TX），F5默认为输入（RX）
    EDIS;

    // 重置SCI
    EALLOW;
    SciaRegs.SCICTL1.all = 0x0000;  // 关闭SCI，准备软件复位
    SciaRegs.SCICTL1.bit.SWRESET = 1;  // 软件复位
    EDIS;

    // 配置SCI通信参数
    SciaRegs.SCICCR.all = 0x0007;  // 8位数据，无校验，1位停止位

    // 设置波特率为9600 (系统时钟150MHz，HISPCLK=75MHz)
    // SCI波特率 = LSPCLK/(SCIHBAUD<<8 + SCILBAUD + 1)/8
    // 对于9600波特率，SCIHBAUD=0, SCILBAUD=0xE7 (实际计算值)
    SciaRegs.SCIHBAUD = 0x00;
    SciaRegs.SCILBAUD = 0xE7;

    // 配置SCI控制寄存器并使能
    EALLOW;
    SciaRegs.SCICTL1.all = 0x0023;  // 释放SWRESET，使能接收器和发送器
    SciaRegs.SCICTL2.all = 0x0000;  // 禁用中断，使用轮询方式
    EDIS;
}

// 检查SCI发送器是否就绪
int SciaTx_Ready(void)
{
    if(SciaRegs.SCICTL2.bit.TXRDY == 1)
    {
        return 1;  // 就绪
    }
    else
    {
        return 0;  // 忙
    }
}

// 检查SCI接收器是否有新数据
int SciaRx_Ready(void)
{
    if(SciaRegs.SCIRXST.bit.RXRDY == 1)
    {
        return 1;  // 有新数据
    }
    else
    {
        return 0;  // 无数据
    }
}

// 发送一个字符
void SciaSendChar(unsigned char data)
{
    while(SciaTx_Ready() == 0) {;}  // 等待发送器就绪
    SciaRegs.SCITXBUF = data;  // 发送数据
}

// 接收一个字符
unsigned char SciaReceiveChar(void)
{
    while(SciaRx_Ready() == 0) {;}  // 等待接收数据
    return SciaRegs.SCIRXBUF.bit.RXDT;  // 返回接收到的数据
}

// 发送字符串
void SciaSendString(char *msg)
{
    int i = 0;
    while(msg[i] != '\0')
    {
        SciaSendChar(msg[i]);
        i++;
    }
}

// 主函数
void main(void)
{
    unsigned char received_char;

    // 系统初始化
    InitSysCtrl();

    // SCI初始化
    InitSci();

    // 发送欢迎信息
    SciaSendString("TMS320F2812 RS232 Communication Test\r\n");
    SciaSendString("Type any character and it will be echoed back.\r\n");

    // 主循环：回显接收到的字符
    for(;;)
    {
        if(SciaRx_Ready())
        {
            received_char = SciaReceiveChar();

            // 回显字符
            SciaSendChar(received_char);

            // 如果收到回车，发送换行符
            if(received_char == '\r')
            {
                SciaSendChar('\n');
            }
        }
    }
}
